//
//  Transitions.swift
//  Smoothly
//
//  Created by jh on 2023/5/15.
//

import SwiftUI

extension AnyTransition {
    static var modal: AnyTransition {
        AnyTransition.modifier(
            active: ThumbnailExpandedModifier(pct: 0),
            identity: ThumbnailExpandedModifier(pct: 1)
        )
    }
    
    struct ThumbnailExpandedModifier: AnimatableModifier {
        var pct: CGFloat
        
        var animatableData: CGFloat {
            get { pct }
            set { pct = newValue }
        }
        
        func body(content: Content) -> some View {
            return content
                .environment(\.modalTransitionPercent, pct)
                .opacity(1)
        }
    }
    
    /// This transition will cause the view to disappear,
    /// until the last frame of the animation is reached
    static var invisible: AnyTransition {
        AnyTransition.modifier(
            active: InvisibleModifier(pct: 0),
            identity: InvisibleModifier(pct: 1)
        )
    }
    
    struct InvisibleModifier: AnimatableModifier {
        var pct: Double
        
        var animatableData: Double {
            get { pct }
            set { pct = newValue }
        }
        
        
        func body(content: Content) -> some View {
            content.opacity(pct == 1.0 ? 1 : 0)
        }
    }
}

struct AnimatableFontModifier: AnimatableModifier {
    var size: Double
    var weight: Font.Weight = .regular
    var design: Font.Design = .default
    
    var animatableData: Double {
        get { size }
        set { size = newValue }
    }
    func body(content: Content) -> some View {
        content
            .font(.system(size: size, weight: weight, design: design))
    }
}

extension View {
    func animatableFont(size: Double, weight: Font.Weight = .regular, design: Font.Design = .default) -> some View {
        self.modifier(AnimatableFontModifier(size: size,weight: weight,design: design))
    }
}

// Use this variable to make all animations super slow, good for debugging transitions
var debugAnimations = false

extension Animation {
    static var hero: Animation { debugAnimations ? debug : .interactiveSpring(response: 0.6, dampingFraction: 0.6, blendDuration: 0.25) }

    static var resetConfig: Animation { debugAnimations ? debug : .interactiveSpring(response: 0.6, dampingFraction: 0.6, blendDuration: 0.25) }

    static var blur: Animation { debugAnimations ? debug : .linear(duration: 0.25) }
    
    static var debug: Animation { .easeInOut(duration: 4.0) }
    
    static let openCard = Animation.spring(response: 0.5, dampingFraction: 0.7)
    static let closeCard = Animation.spring(response: 0.6, dampingFraction: 0.9)
    
    static let cusIn = Animation.easeIn(duration: 0.5)
    static let cusOut = Animation.easeIn(duration: 0.5)
}
